<?php

namespace app\vpn\admin;

use app\common\builder\ZBuilder;
use app\vpn\model\Node as NodeModel;
use app\vpn\model\VpnConfig as ConfigModel;
use app\vpn\model\Country as CountryModel;
use app\admin\model\Module as ModuleModel;
use think\facade\Env;

/**
 * 节点控制器
 */
class Node extends Index
{

    protected function initialize()
    {
        parent::initialize();
        if ($this->no_auth) {
            $this->error('权限不足！');
        }
    }

    /**
     * 首页
     * @return mixed
     */
    public function index()
    {
        // 设置搜索参数
        $search = ['assort' => '分类', 'country_title' => '国家中文', 'rank' => '等级', 'status' => '状态'];

        // 获取查询条件
        $map = $this->getMap();

        $list_rows = input('list_rows', 20) >= 20 ? 20 : input('list_rows');
        // 数据列表
        $data_list = NodeModel::where($map)->order('sort desc,cid desc,create_time desc')->paginate($list_rows);
        // 分页数据
        $page = $data_list->render();

        $status_type = $this->role > $this->have_auth ? 'status' : 'switch';
        $items = [
            ['cid', 'ID'],
            ['assort', '分类'],
            ['address', '地址'],
            ['remarks', '别名'],
            ['country_title', '国家中文'],
            ['icon', '图标', 'picture'],
            ['rank', '等级', '', '', ['游客', '普通会员', '高级会员']],
            ['create_time', '创建时间', 'datetime', '', 'Y-m-d H:i:s'],
            ['status', '状态', $status_type],
            ['right_button', '操作', 'btn']
        ];
        $hideCheckbox = false;
        if ($this->no_auth) {
            $hideCheckbox = true;
        }

        // 节点链接导入
        $link = [
            'title' => '节点链接导入',
            'icon' => 'fa fa-fw fa-deviantart',
            'class' => 'btn btn-info',
            'href' => url('link'),
        ];
        // 使用ZBuilder快速创建数据表格
        return ZBuilder::make('table')
            ->hideCheckbox($hideCheckbox)
            ->setPageTitle('节点管理') // 设置页面标题
            ->setTableName('vpn_node') // 设置数据表名
            ->setPrimaryKey('cid') // 设置主键名为id
            ->setSearch($search) // 设置搜索参数
            ->addColumns($items)
            ->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
            ->addTopButton('link', $link) // 添加按钮
            ->addRightButton('see', ['title' => '查看', 'icon' => 'fa fa-fw fa-eye', 'href' => url('see', ['id' => '__id__'])], true)
            ->addRightButtons('edit,delete') // 批量添加右侧按钮
            ->setRowList($data_list) // 设置表格数据
            ->setPages($page) // 设置分页数据
            ->fetch(); // 渲染页面
    }

    /**
     * 节点链接导入
     * @param null $id 
     * @return mixed
     */
    public function link()
    {
        // 保存数据
        if ($this->request->isPost()) {
            $data = $this->request->post();

            // 验证
            $validate = \think\Validate::make([
                'link|节点链接' => 'require',
            ]);

            if (!$validate->check($data)) {
                $this->error($validate->getError());
            }

            $node = preg_split('/[,;\r\n]+/', trim($data['link'], ",;\r\n"));

            $arr = [];

            foreach ($node as $value) {

                if (strpos($value, 'ssr://') !== false) {
                    $type = 'ssr';
                } elseif (strpos($value, 'vmess://') !== false) {
                    $type = 'vmess';
                } elseif (strpos($value, 'ss://') !== false) {
                    $type = 'ss';
                } elseif (strpos($value, 'socks://') !== false) {
                    $type = 'socks';
                } elseif (strpos($value, 'trojan://') !== false) {
                    $type = 'trojan';
                } else {
                    $type = '';
                }
                $arr[] = node_analyze($type, $value);
            }

            if (isset($data['save'])) {
                halt($arr);
            }

            $node_add = new NodeModel;
            if ($node_add->saveAll($arr)) {
                $this->success('新增成功', url('index'));
            } else {
                $this->error('新增失败');
            }
        }

        $items = [
            ['textarea', 'link', '节点链接', '多个节点链接换行区分'],
        ];

        // 使用ZBuilder快速创建表单
        return ZBuilder::make('form')
            ->setPageTitle('导入节点链接') // 设置页面标题
            ->addFormItems($items)
            ->addBtn('<button class="btn btn-rounded btn-success" target-form="form-builder" type="submit" name="save">查看</button>')
            ->fetch();
    }

    /**
     * 新增
     * @return mixed
     */
    public function add($group = '')
    {
        // 配置分组信息
        $list_group = vpn_config('config_group');
        if (isset($list_group['vpn_config'])) {
            unset($list_group['vpn_config']);
        }
        $group = $group ? $group : array_key_first($list_group);

        // 保存数据
        if ($this->request->isPost()) {
            $data = $this->request->post();

            // 验证
            $result = $this->validate($data, 'Node');

            // 验证失败 输出错误信息
            if (true !== $result) {
                $this->error($result);
            }

            if ($data['country']) {
                $country = CountryModel::where(['id' => $data['country']])->find();
                if ($country) {
                    $data['country_title'] = $country['country_title'];
                    $data['country_name'] = $country['country_name'];
                    $data['country_abbr'] = $country['country_abbr'];
                    $data['icon'] = $country['icon'];
                }
            }

            $data['remarks'] = $data['remarks'] ? $data['remarks'] : (isset($data['country_title']) ? $data['country_title'] : '');

            $data['assort'] = $group;

            if (NodeModel::create($data)) {
                // 记录行为             
                $this->success('新增成功', url('index'));
            } else {
                $this->error('新增失败');
            }
        }

        $tab_list = [];
        foreach ($list_group as $key => $value) {
            $tab_list[$key]['title'] = $value;
            $tab_list[$key]['url'] = url('add', ['group' => $key]);
        }

        if (isset($list_group[$group])) {
            // 查询条件
            $map['group'] = $group;
            $map['status'] = 1;

            // 数据列表
            $data_list = ConfigModel::where($map)
                ->order('sort asc,id asc')
                ->field('group', true)
                ->select();
            $data_list = $data_list->toArray();

            foreach ($data_list as &$value) {
                // 解析options
                if ($value['options'] != '') {
                    $value['options'] = parse_attr($value['options']);
                }
                // 默认模块列表
                if ($value['name'] == 'home_default_module') {
                    $value['options'] = array_merge(['index' => '默认'], ModuleModel::getModule());
                }
                switch ($value['type']) {
                        // 日期时间
                    case 'date':
                        $value['value'] = $value['value'] != '' ? date('Y-m-d', $value['value']) : '';
                        break;
                    case 'time':
                        $value['value'] = $value['value'] != '' ? date('H:i:s', $value['value']) : '';
                        break;
                    case 'datetime':
                        $value['value'] = $value['value'] != '' ? date('Y-m-d H:i:s', $value['value']) : '';
                        break;
                    case 'linkages':
                        $value['token'] = $this->createLinkagesToken($value['table'], $value['option'], $value['key']);
                        break;
                    case 'colorpicker':
                        $value['mode'] = 'rgba';
                        break;
                }
            }

            $add_data = [
                [
                    'name' => 'rank',
                    'title' => '用户等级',
                    'type' => 'radio',
                    'value' => 0,
                    'options' => ['游客', '普通会员', '高级会员'],
                    'tips' => '',
                ],
                [
                    'name' => 'status',
                    'title' => '状态',
                    'type' => 'radio',
                    'value' => 1,
                    'options' => ['禁用', '启用'],
                    'tips' => '',
                ],
            ];

            $all_country = CountryModel::where(['status' => 1])->column('country_title', 'id');

            $data_list = array_merge([[
                'name' => 'country',
                'title' => '国家中文',
                'type' => 'select',
                'value' => '',
                'options' => $all_country,
                'tips' => '',
            ]], $data_list,  $add_data);

            // 使用ZBuilder快速创建表单
            return ZBuilder::make('form')
                ->setPageTitle('节点设置')
                ->setTabNav($tab_list, $group)
                ->setFormItems($data_list)
                ->fetch();
        }
    }

    /**
     * 查看
     * @param null $id 
     * @return mixed
     */
    public function see($id = null)
    {
        if ($id === null) {
            $this->error('缺少参数！');
        }

        // 获取数据
        $info = NodeModel::where('cid', $id)->field(true)->find();
        if (!$info) {
            $this->error('不存在！');
        }

        $link = node_generate($info['assort'], $info);

        include_once Env::get('extend_path') . 'phpqrcode' . DIRECTORY_SEPARATOR . 'phpqrcode.php';
        $object = new \QRcode('null');
        $link_image = $object->png($link, false, 'L', 3, 1);

        $link_image = ob_get_contents();
        // 清空缓存
        ob_clean();
        $img = '<img src="data:image/png;base64,' . base64_encode($link_image) . '" />';

        $group = $info['assort'];

        // 查询条件
        $map['group'] = $group;
        $map['status'] = 1;

        // 数据列表
        $data_list = ConfigModel::where($map)
            ->order('sort asc,id asc')
            ->field('group', true)
            ->select();
        $data_list = $data_list->toArray();

        $arr = [];
        foreach ($data_list as &$value) {
            // 解析options
            if ($value['options'] != '') {
                $value['options'] = parse_attr($value['options']);
            }
            // 默认模块列表
            if ($value['name'] == 'home_default_module') {
                $value['options'] = array_merge(['index' => '默认'], ModuleModel::getModule());
            }
            switch ($value['type']) {
                    // 日期时间
                case 'date':
                    $value['value'] = $value['value'] != '' ? date('Y-m-d', $value['value']) : '';
                    break;
                case 'time':
                    $value['value'] = $value['value'] != '' ? date('H:i:s', $value['value']) : '';
                    break;
                case 'datetime':
                    $value['value'] = $value['value'] != '' ? date('Y-m-d H:i:s', $value['value']) : '';
                    break;
                case 'linkages':
                    $value['token'] = $this->createLinkagesToken($value['table'], $value['option'], $value['key']);
                    break;
                case 'colorpicker':
                    $value['mode'] = 'rgba';
                    break;
            }
            $arr[] = ['static', $value['name'], $value['title'], $value['tips']];
        }

        $link = [['text', 'link', '链接', "<code>$img</code>", $link]];

        $items = [
            ['static', 'country_title', '国家中文'],
            ['static', 'country_name', '国家英文'],
            ['static', 'country_abbr', '国家缩写'],
            ['image', 'icon', '图片'],
            ['static', 'cid', 'ID', '', $id],
            ['static', 'assort', '节点类型', '',],
            ['radio', 'rank', '等级', '', ['游客', '普通会员', '高级会员']],
            ['radio', 'status', '状态', '', ['禁用', '启用']],
            ['datetime', 'create_time', '创建时间', '', '', 'YYYY-MM-DD HH:mm:ss', 'disabled'],
            ['datetime', 'update_time', '更新时间', '', '', 'YYYY-MM-DD HH:mm:ss', 'disabled'],
        ];

        $data_list = array_merge($link, $arr, $items);


        // 使用ZBuilder快速创建表单
        return ZBuilder::make('form')
            ->setPageTitle('查看') // 设置页面标题
            ->addFormItems($data_list)
            ->hideBtn('submit')
            ->setFormData($info) // 设置表单数据
            ->fetch();
    }

    /**
     * 编辑
     * @param null $id 
     * @return mixed
     */
    public function edit($id = null)
    {
        if ($id === null) {
            $this->error('缺少参数！');
        }

        // 保存数据
        if ($this->request->isPost()) {
            $data = $this->request->post();

            // 验证
            $result = $this->validate($data, 'Node');
            // 验证失败 输出错误信息
            if (true !== $result) {
                $this->error($result);
            }

            if (isset($data['country'])) {
                $country = CountryModel::where(['id' => $data['country']])->find();
                if ($country) {
                    $data['country_title'] = $country['country_title'];
                    $data['country_name'] = $country['country_name'];
                    $data['country_abbr'] = $country['country_abbr'];
                    $data['icon'] = $country['icon'];
                }
            }

            if (NodeModel::update($data)) {
                $this->success('编辑成功', url('index'));
            } else {
                $this->error('编辑失败');
            }
        }

        // 获取数据
        $info = NodeModel::where('cid', $id)->find();
        if (!$info) {
            $this->error('不存在！');
        }

        $group = $info['assort'];

        // 查询条件
        $map['group'] = $group;
        $map['status'] = 1;

        // 数据列表
        $data_list = ConfigModel::where($map)
            ->order('sort asc,id asc')
            ->field('group', true)
            ->select();
        $data_list = $data_list->toArray();

        $arr = [];
        foreach ($data_list as &$value) {
            // 解析options
            if ($value['options'] != '') {
                $value['options'] = parse_attr($value['options']);
            }
            // 默认模块列表
            if ($value['name'] == 'home_default_module') {
                $value['options'] = array_merge(['index' => '默认'], ModuleModel::getModule());
            }
            switch ($value['type']) {
                    // 日期时间
                case 'date':
                    $value['value'] = $value['value'] != '' ? date('Y-m-d', $value['value']) : '';
                    break;
                case 'time':
                    $value['value'] = $value['value'] != '' ? date('H:i:s', $value['value']) : '';
                    break;
                case 'datetime':
                    $value['value'] = $value['value'] != '' ? date('Y-m-d H:i:s', $value['value']) : '';
                    break;
                case 'linkages':
                    $value['token'] = $this->createLinkagesToken($value['table'], $value['option'], $value['key']);
                    break;
                case 'colorpicker':
                    $value['mode'] = 'rgba';
                    break;
            }
            $arr[] = ['text', $value['name'], $value['title'], $value['tips']];
        }

        $all_country = CountryModel::where(['status' => 1])->column('country_title', 'id');

        $gj = [
            ['text', 'country_title', '国家中文'],
            ['text', 'country_name', '国家英文'],
            ['text', 'country_abbr', '国家缩写'],
            ['image', 'icon', '图片'],
        ];
        if (empty($info['country_title']) || empty($info['country_name']) || empty($info['country_abbr'])) {
            $gj = [['select', 'country', '国家中文', '', $all_country]];
        }

        $items = [
            ['static', 'cid', 'ID', '', $id],
            ['static', 'assort', '节点类型', '',],
            ['radio', 'rank', '等级', '', ['游客', '普通会员', '高级会员']],
            ['radio', 'status', '状态', '', ['禁用', '启用']],
            ['datetime', 'create_time', '创建时间', '', '', 'YYYY-MM-DD HH:mm:ss', 'disabled'],
            ['datetime', 'update_time', '更新时间', '', '', 'YYYY-MM-DD HH:mm:ss', 'disabled'],
        ];

        $data_list = array_merge($gj, $arr, $items);

        // 使用ZBuilder快速创建表单
        return ZBuilder::make('form')
            ->setPageTitle('编辑') // 设置页面标题
            ->addHidden('cid')
            ->addFormItems($data_list)
            ->setFormData($info) // 设置表单数据
            ->fetch();
    }

    /**
     * 删除
     * @param array $record 
     * @return mixed
     */
    public function delete($record = [])
    {
        return $this->setStatus('delete');
    }

    /**
     * 启用
     * @param array $record 
     * @return mixed
     */
    public function enable($record = [])
    {
        return $this->setStatus('enable');
    }

    /**
     * 禁用
     * @param array $record 
     * @return mixed
     */
    public function disable($record = [])
    {
        return $this->setStatus('disable');
    }

    /**
     * 设置状态：删除、禁用、启用
     * @param string $type 类型：delete/enable/disable
     * @param array $record 
     * @return mixed
     */
    public function setStatus($type = '', $record = [])
    {
        $ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
        $ids_delete = is_array($ids) ? '' : $ids;
        $data = NodeModel::where('cid', 'in', $ids)->column('cid');
        return parent::setStatus($type, ['vpn_node_' . $type, 'vpn_node', $ids_delete, UID, implode('、', $data)]);
    }

    /**
     * 快速编辑
     * @param array $record 行为日志
     * @return mixed
     */
    public function quickEdit($record = [])
    {
        $id = input('post.pk', '');
        $field = input('post.name', '');
        $value = input('post.value', '');
        $data = NodeModel::where('cid', $id)->value($field);
        $details = '字段(' . $field . ')，原值(' . $data . ')，新值：(' . $value . ')';
        return parent::quickEdit(['vpn_node_edit', 'vpn_node', $id, UID, $details]);
    }

    /**
     * 创建快速多级联动Token
     * @param string $table 表名
     * @param string $option
     * @param string $key
     * @author 蔡伟明 <314013107@qq.com>
     * @return bool|string
     */
    private function createLinkagesToken($table = '', $option = '', $key = '')
    {
        $table_token = substr(sha1($table . '-' . $option . '-' . $key . '-' . session('user_auth.last_login_ip') . '-' . UID . '-' . session('user_auth.last_login_time')), 0, 8);
        session($table_token, ['table' => $table, 'option' => $option, 'key' => $key]);
        return $table_token;
    }
}
